<template>
	<div class="groupArea">
		<template v-for="item in nav">
			<!-- 单个组件 -->
			<div
				:key="item"
				class="sub-single-comp"
				:class="[item.component.name == 'iframe' ? 'iframe' : '']"
				v-if="!item.children"
				v-contextmenu="{
					id: contain.menuId,
					event: contain.handleContextMenu,
					value: item
				}"
			>
				<!-- disabled控制是否禁止拖动 -->
				<avue-draggable
					:id="common.DEAFNAME + item.index"
					:ref="common.DEAFNAME + item.index"
					:scale="container.stepScale"
					:disabled="isBuild ? item.isLock : true"
					:step="container.stepScale"
					:width="item.component.width"
					:height="item.component.height"
					:left="item.left"
					:top="item.top"
					:active-flag="contain.active.includes(item.index)"
					v-show="item.display"
					v-bind="item"
					@move="handleMove"
					@over="handleOver"
					@blur="handleBlur"
					@focus="e => handleFocus(item, e)"
				>
					<component
						:style="{
							overflow: 'hidden',
							'pointer-events': item.pointerEvent ? 'none' : 'all',
							filter: contain.config.filter && contain.config.filter.show ? computedFilter(contain.config.filter) : 'none',
							opacity: item.isLock ? 0.7 : 1
						}"
						:ref="common.NAME + item.index"
						:id="common.NAME + item.index"
						:is="common.COMPNAME + item.component.name"
						:appendParams="item.appendParams"
						v-bind="item"
						:component="item.component"
						:data-formatter="item.dataFormatter"
						:click-formatter="getFunction(item.clickFormatter, true)"
						:echart-formatter="getFunction(item.echartFormatter)"
						:label-formatter="getFunction(item.labelFormatter)"
						:styles-formatter="getFunction(item.stylesFormatter)"
						:formatter="getFunction(item.formatter)"
						:data-query="getFunction(item.dataQuery)"
						:data-header="getFunction(item.dataHeader)"
						:sql-formatter="sqlFormatter"
						:width="item.component.width"
						:height="item.component.height"
						:left="item.left"
						:top="item.top"
						:disabled="isBuild ? item.isLock : true"
						:scale="container.stepScale"
						:display.sync="item.display"
						:title="item.title"
						:ratio="contain.config.scale / 100 + 0.001"
						:isReceiveDataComp="item.isReceiveDataComp"
					/>
					<i v-if="isBuild && item.isLock" class="lockIcon el-icon-lock"></i>
				</avue-draggable>
			</div>
			<!-- 成组 -->
			<div v-else class="sub-group-children-comp">
				<avue-draggable
					:id="common.DEAFNAME + item.index"
					:ref="common.DEAFNAME + item.index"
					:scale="container.stepScale"
					:disabled="isBuild ? item.isLock : true"
					:step="container.stepScale"
					:width="item.component.width"
					:height="item.component.height"
					:left="item.left"
					:top="item.top"
					:active-flag="contain.active.includes(item.index)"
					v-show="item.display"
					v-bind="item"
					@move="handleGroupMove"
					@over="handleOver"
					@blur="handleGroupBlur"
					@focus="e => handleGroupFocus(item, e)"
				>
					<div
						v-for="gItem in item.children"
						:key="common.DEAFNAME + gItem.index"
						:style="{
							width: gItem.component.width + 'px',
							height: gItem.component.height + 'px',
							left: gItem.left + 'px',
							top: gItem.top + 'px',
							position: 'absolute'
						}"
					>
						<component
							:style="{
								overflow: 'hidden',
								'pointer-events': gItem.pointerEvent ? 'none' : 'all',
								filter: contain.config.filter && contain.config.filter.show ? computedFilter(contain.config.filter) : 'none',
								opacity: gItem.isLock ? 0.7 : 1
							}"
							:ref="common.NAME + gItem.index"
							:id="common.NAME + gItem.index"
							:is="common.COMPNAME + gItem.component.name"
							:appendParams="gItem.appendParams"
							v-bind="gItem"
							:component="gItem.component"
							:data-formatter="gItem.dataFormatter"
							:click-formatter="getFunction(gItem.clickFormatter, true)"
							:echart-formatter="getFunction(gItem.echartFormatter)"
							:label-formatter="getFunction(gItem.labelFormatter)"
							:styles-formatter="getFunction(gItem.stylesFormatter)"
							:formatter="getFunction(gItem.formatter)"
							:data-query="getFunction(gItem.dataQuery)"
							:data-header="getFunction(gItem.dataHeader)"
							:sql-formatter="sqlFormatter"
							:width="gItem.component.width"
							:height="gItem.component.height"
							:disabled="isBuild ? gItem.isLock : true"
							:scale="container.stepScale"
							:display.sync="gItem.display"
							:title="gItem.title"
							:ratio="contain.config.scale / 100 + 0.001"
						/>
					</div>

					<!-- 单个组件 -->

					<i v-if="isBuild && item.isLock" class="lockIcon el-icon-lock"></i>
				</avue-draggable>
			</div>
		</template>
		<!-- 标线 -->
		<MarkLine ref="markLine" v-if="activeCompsIndex && activeCompsIndex.length > 0"></MarkLine>
	</div>
</template>

<script>
//注册自定义组件
import components from '@/components/';
import MarkLine from '@/page/group/MarkLine.vue';
import crypto from '@/utils/crypto';
import { dynamicSql } from '@/api/db';
import { config } from '@/option/config';
import { getFunction } from '@/utils/utils';
import common from '@/config';
import echartComponents from '../../echart/';
import { mapState, mapGetters } from 'vuex';
export default {
	name: 'subgroup',
	inject: ['contain', 'container'],
	provide() {
		return {
			contain: this.contain,
			container: this.container,
			allCompContainer: this
		};
	},
	components: {
		components,
		MarkLine
	},
	props: {
		nav: {
			type: Array,
			default: () => {
				return [];
			}
		}
	},
	data() {
		return {
			sqlFormatter: dynamicSql,
			common: common
		};
	},
	computed: {
		...mapState({
			globalEventList: state => state.event.globalEventList,
			activeComps: state => state.activeComps,
			compsList: state => state.compsList,
			areaData: state => state.areaData
		}),
		...mapGetters(['activeCompsIndex']),
		computedFilter(filter) {
			return filter => {
				return `contrast(${filter.contrast}%) brightness(${filter.brightness}%) opacity(${filter.opacity}%) saturate(${filter.saturate}%) hue-rotate(${filter['hue-rotate']}deg)`;
			};
		},
		isBuild() {
			return this.$route ? this.$route.name === 'build' : false;
		},
		isKeysCtrl() {
			return this.contain.isKeysCtrl;
		},
		groupChildrenStyle() {
			return item => {
				let obj = {
					width: item.component.width + 'px',
					height: item.component.height + 'px',
					left: item.left + 'px',
					top: item.top + 'px',
					position: 'relative'
				};
				return obj;
			};
		}
	},
	created() {
		this.init();
	},
	methods: {
		init() {
			Object.keys(echartComponents).map(ele => {
				let component = echartComponents[ele];
				Vue.component(component.name, component);
			});
			this.getFunction = getFunction;
		},
		getItemObj() {
			if (
				this.contain.activeObj &&
				this.contain.activeObj.index &&
				this.$refs[this.common.NAME + this.contain.activeObj.index] &&
				this.$refs[this.common.NAME + this.contain.activeObj.index].length > 0
			) {
				return this.$refs[this.common.NAME + this.contain.activeObj.index][0];
			}
		},
		//刷新数据
		handleRefresh() {
			try {
				let itemObj = this.getItemObj();
				if (itemObj) {
					return itemObj.updateData();
				}
			} catch (error) {
				console.log('error', error);
			}
		},
		//获取对象
		getDragObj(val) {
			return this.$refs[`${this.common.DEAFNAME}${val}`];
		},
		// 清除画布内所有组件的选中状态
		clearAllCompsActive() {
			let activeDom = document.querySelectorAll('.groupArea .avue-draggable--active');
			activeDom.forEach(dom => {
				dom.classList.remove('avue-draggable--active');
				let lineDom = dom.querySelectorAll('.avue-draggable__wrapper .avue-draggable__line');
				let rangeDom = dom.querySelectorAll('.avue-draggable__wrapper .avue-draggable__range');

				lineDom.forEach(lDom => {
					lDom.style.display = 'none';
				});
				rangeDom.forEach(rDom => {
					rDom.style.display = 'none';
				});
			});
		},
		// 激活指定组件
		setCompsActive(compsIndex) {
			this.$nextTick(() => {
				let activeDom = document.querySelectorAll('.groupArea .avue-draggable--active');
				activeDom.forEach(dom => {
					let lineDom = dom.querySelectorAll('.avue-draggable__wrapper .avue-draggable__line');
					let rangeDom = dom.querySelectorAll('.avue-draggable__wrapper .avue-draggable__range');

					lineDom.forEach(lDom => {
						lDom.style.display = 'block';
					});
					rangeDom.forEach(rDom => {
						rDom.style.display = 'block';
					});
				});
				compsIndex.map(act => {
					let refIndex = `${this.common.DEAFNAME}${act}`;
					if (this.$refs[refIndex] && this.$refs[refIndex][0]) {
						this.$refs[refIndex][0].setActive(true);
					}
				});
			});
		},
		handleMove({ index, left, top, isLock }) {
			if (!this.activeCompsIndex.includes(index)) return;
			this.activeComps.forEach(item => {
				// if (this.activeCompsIndex.includes(item.index)) return;
				item.left = item.left + left;
				item.top = item.top + top;
				// 更新完当前组件的样式后 吸附
				this.$nextTick(() => {
					// 触发元素移动，用于显示标线、吸附功能；后面两个参数代表鼠标移动方向
					this.$refs.markLine.showLine(left > 0, top > 0);
				});
			});
		},
		handleOver({ index }) {
			this.contain.overactive = index;
		},
		handleFocus(item, e) {
			let { index, isLock = false } = item;
			this.$parent.hideArea();
			if (!this.isKeysCtrl && this.activeComps.length > 0) {
				//  清除组件选中状态
				this.activeComps.map(act => {
					if (act.index == index) return;
					let refIndex = `${this.common.DEAFNAME}${act.index}`;
					if (this.$refs[refIndex] && this.$refs[refIndex][0]) {
						this.$refs[refIndex][0].setActive(false);
					}
				});
			}
			this.$store.commit('setActiveComps', {
				isKeysCtrl: this.isKeysCtrl,
				...item
			});
		},
		handleBlur({ index, left, top, width, height }) {
			this.$refs.markLine && this.$refs.markLine.hideLine();
			if (!this.activeComps.find(comp => comp.index == index)) return;
			if (!this.isKeysCtrl) {
				if (this.contain.activeObj && this.contain.activeObj.component) {
					this.$set(this.contain.activeObj.component, 'width', width);
					this.$set(this.contain.activeObj.component, 'height', height);
					this.$set(this.contain.activeObj, 'left', left);
					this.$set(this.contain.activeObj, 'top', top);
				}
			}
		},

		handleGroupMove({ index, left, top, isLock }) {
			if (!this.activeCompsIndex.includes(index)) return;
			let areaComponents = this.activeComps[0].children;
			areaComponents.forEach(item => {
				item.oldLeft = item.oldLeft + left;
				item.oldTop = item.oldTop + top;
			});
		},
		handleGroupFocus(item, e) {
			let { index, isLock = false } = item;
			this.$parent.hideArea();

			this.$store.commit('clearActiveComps');
			this.$store.commit('setActiveComps', {
				isKeysCtrl: this.isKeysCtrl,
				...item
			});
		},
		handleGroupBlur(item) {
			let { index, left, top, width, height } = item;
			if (!this.activeComps.find(comp => comp.index == index)) return;

			if (!this.isKeysCtrl) {
				if (this.contain.activeObj && this.contain.activeObj.component) {
					this.$set(this.contain.activeObj.component, 'width', width);
					this.$set(this.contain.activeObj.component, 'height', height);
					this.$set(this.contain.activeObj, 'left', left);
					this.$set(this.contain.activeObj, 'top', top);
				}
			}
			let areaComponents = this.activeComps[0].children;
			//设置选中区域位移大小信息和区域内的组件数据
			this.$store.commit('setAreaData', {
				style: {
					left: left,
					top: top,
					width: width,
					height: height
				},
				activeComps: this.activeComps,
				isGroup: true,
				components: areaComponents
			});
		}
	}
};
</script>
